home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
WINPROGS
/
MODEM2.ZIP
/
MODEM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-11
|
16KB
|
571 lines
/*
This program is the simplest of simple serial communications apps.
I wrote it to learn myself how to use a modem in windows. I have had
success using two copies of it to communicate across phone lines with
one another. For other serial devices, I doubt this program is Appropriate.
It is written under TC++ 3.0/win and should work under any Borland
windows compiler in windows 3.1. Be sure to include the resource file
in the program, or create your own resources.
An interesting note on functionality: Most of the demo programs
I've seen advocate using the Idle() procedure in the TApplication object
to process incoming information from the port. However, from my own
experience, THIS IS NOT THE WAY TO DO IT! Instead, this program lets
Windows send it messages telling it when to read the buffer etc...
Good luck, and email me at
jawhitti@midway.ecn.uoknor.edu
if you have any questions. The program runs to near 600 lines, but is
really quite simple. Don't be intimidated!
*/
#define STRICT
#define WIN31
/* if you want to use the dynamic libraries, set memory model to large,
and case-sensitive link to off, and leave _CLASSDLL defined. Otherwise
comment it out. */
#define _CLASSDLL
#include <owl.h>
#include <edit.h>
/* bwindow is not necessary, it just makes a gray window. The program
works just the same if you derive TSerialWindow from TWindow. */
#include <bwindow.h>
// #defines for the program. Change them to fit your resources,etc...
#define CM_DIAL 101
#define CM_HANGUP 102
#define UM_ERROR WM_USER+1
#define UM_DATA WM_USER+2
// Size of buffer to recieve incoming text...
#define MAXINPUTLENGTH 80
// Size of Phone number buffer...
#define PHONEINPUTLENGTH 25
_CLASSDEF(TSerialApp)
// TSerial app is just a TApplication that sets up a TSerialWindow
class TSerialApp : public TApplication
{
public:
TSerialApp(LPSTR Aname, HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
: TApplication(Aname, hInstance, hPrevInstance, lpCmdLine, nCmdShow){};
virtual void InitMainWindow();
};
_CLASSDEF(TSerialWindow)
class TSerialWindow: public TBWindow
{
/* This class is the backbone of the program. It likely is not the BEST
way to do things, but it works. I plan to modify it to make it more
easily inherited. Do as you please... */
public:
// Handle to Borland custom controls...
HANDLE BWCCMod;
char PhoneNumber[PHONEINPUTLENGTH];
char Command[MAXINPUTLENGTH];
//CPort holds the current open COM Port, y controls a primitive
//Screen scroll.
int CPort,y;
TSerialWindow(PTWindowsObject AParent, LPSTR ATitle);
virtual void SetupWindow();
virtual void CloseWindow();
virtual void CommEvent();
virtual void CheckReceiveBuffer();
virtual void DialPhone(RTMessage Msg) = [CM_FIRST+ 101];
virtual void SendText(RTMessage Msg) = [CM_FIRST+ 102];
virtual void GetStatus(RTMessage Msg) = [CM_FIRST+ 103];
virtual void SendCommand(RTMessage Msg)= [CM_FIRST+ 104];
virtual void SerError(RTMessage Msg) = [WM_FIRST+UM_ERROR];
virtual void SerData(RTMessage Msg) = [WM_FIRST+UM_DATA];
//This procedure is important, and must be enabled in SetupWindow
//with the ENABLECOMMNOTIFICATION call.
virtual int CommNotification(RTMessage Msg) = [WM_COMMNOTIFY];
};
//These dialog classes control some simple dialogs. Play with them
//to make the program more fun.
//Get user input.
_CLASSDEF(TMyInputDialog)
class TMyInputDialog : public TDialog
{
public : TMyInputDialog(PTWindowsObject AParent, LPSTR AResource);
};
//Get Phone number
_CLASSDEF(TPhoneInputDialog)
class TPhoneInputDialog : public TDialog
{
public : TPhoneInputDialog(PTWindowsObject AParent, LPSTR AResource);
};
//Select a COM port. Default is COM2
_CLASSDEF(TCommPortDialog)
class TCommPortDialog : public TDialog
{
public : TCommPortDialog(PTWindowsObject AParent, LPSTR AResource);
private:
void PickOne(RTMessage Msg) = [ID_FIRST + 101];
void PickTwo(RTMessage Msg) = [ID_FIRST + 102];
void PickThree(RTMessage Msg)= [ID_FIRST + 103];
void PickFour(RTMessage Msg) = [ID_FIRST + 104];
};
void TSerialApp::InitMainWindow()
{
MainWindow = new TSerialWindow(NULL,Name);
}
//******************************************************
// TSerialWindow member functions... *
//******************************************************
TSerialWindow::TSerialWindow(PTWindowsObject AParent, LPSTR ATitle)
: TBWindow(AParent,ATitle)
//Simple constructor does nothing special
{
PhoneNumber[0] = '\0';
CPort = -1; y=10;
AssignMenu("MENU_1");
BWCCMod=LoadLibrary("BWCC.DLL");
}
void TSerialWindow::SetupWindow()
{
int WhichPort;
DCB CommData;
LPSTR ACommPort;
TBWindow::SetupWindow();
MessageBeep(MB_OK);
//Get the COM Port preference...
WhichPort=GetModule()->ExecDialog(new TCommPortDialog(this, "DIALOG_3"));
switch(WhichPort)
{
case 1: CPort = OpenComm("COM1", 1024, 1024); break;
case 3: CPort = OpenComm("COM3", 1024, 1024); break;
case 4: CPort = OpenComm("COM4", 1024, 1024); break;
default:CPort = OpenComm("COM2", 1024, 1024); break;
}
//OpenComm is <0 if the port fails to open...
if(CPort < 0)
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(HWindow,"Comm port not open","Uh-Oh",MB_OK);
}
//Retrieve default Port settings...
GetCommState(CPort, &CommData);
//Adjust for app specific parameters....
CommData.BaudRate = 2400;
CommData.ByteSize = 8;
CommData.Parity = NOPARITY;
CommData.StopBits = ONESTOPBIT;
CommData.DsrTimeout =1000;
//Set the COM port to new parameters...
if(SetCommState(&CommData)!=0)
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(HWindow,"Comm Port not configured","Error",MB_OK+MB_ICONEXCLAMATION);
}
//Flush Input and output buffers...
FlushComm(CPort,0); FlushComm(CPort,1);
//Tell windows to send CommNotification messages to this window...
if (EnableCommNotification(CPort,HWindow,160,-1)==0)
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(HWindow,"EnableCommNotification Failed","Error",MB_OK+MB_ICONEXCLAMATION);
}
//Tell windows to notify program of ANY comport message...
SetCommEventMask(CPort,0xFFFF);
//Modem Initialization string. Set to whatever...
WriteComm(CPort,"ATE1 S12=10\r",13);
}
void TSerialWindow::CloseWindow()
{
CloseComm(CPort);
TBWindow::CloseWindow();
}
void TSerialWindow::CheckReceiveBuffer()
//This program looks in the recieve buffer and retrieves information
//in it into Buffer. If an error occurs, a UM_ERROR message is sent,
//else a UM_DATA message is sent, with a pointer to the data in LParam.
{
int Ret,Err,i;
char Buffer[80];
COMSTAT Comstat;
for(i=0;i<80;i++)Buffer[i]='\0';
if(CPort>=0)
{
Ret = ReadComm(CPort, Buffer, 80);
if(Ret<0)
{
Err = GetCommError(CPort, &Comstat);
if(Err>0)SendMessage(HWindow, UM_ERROR, 3, Err);
}
if(Ret>0)
{
SendMessage(HWindow, UM_DATA,Ret,(long)Buffer);
}
}
}
void TSerialWindow::CommEvent()
{
int event;
char Buffer[80];
//Simple procedure Filters event messages. For most, simply
//sends a message to itself to write on the sreen what the
//message was. Events are coded it a bitfield, so each IF checks
//for a specific flag. Several flags may be checked at once, so
//a SWITCH is not practical.
event = GetCommEventMask(CPort,0xFFFF);
if(event & EV_BREAK)
{
wsprintf(Buffer,"EV_BREAK");
SendMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
}
if(event & EV_CTS)
{
wsprintf(Buffer,"EV_CTS");
SendMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
}
if(event & EV_CTSS)
{
wsprintf(Buffer,"EV CTSS...");
PostMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
}
if(event & EV_DSR)
{
wsprintf(Buffer,"EV_DSR");
SendMessage(HWindow,UM_DATA,lstrlen(Buffer),(long)Buffer);
}
if(event & EV_ERR)
{
wsprintf(Buffer,"EV_ERR");
SendMes